package cn.lystudio.rohm_time_op.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.system.UserInfo;
import cn.lystudio.rohm_time_op.entity.dto.UserDepartmentDTO;
import cn.lystudio.rohm_time_op.entity.dto.UserInfoDTO;
import cn.lystudio.rohm_time_op.entity.dto.UserRoleDTO;
import cn.lystudio.rohm_time_op.entity.po.DepartmentsPO;
import cn.lystudio.rohm_time_op.entity.po.RolesPO;
import cn.lystudio.rohm_time_op.entity.po.UsersDepartmentPO;
import cn.lystudio.rohm_time_op.entity.po.UsersPO;
import cn.lystudio.rohm_time_op.exceptions.JsonException;
import cn.lystudio.rohm_time_op.mapper.DepartmentsPOMapper;
import cn.lystudio.rohm_time_op.mapper.RolesPOMapper;
import cn.lystudio.rohm_time_op.mapper.UsersDepartmentPOMapper;
import cn.lystudio.rohm_time_op.mapper.UsersPOMapper;
import cn.lystudio.rohm_time_op.service.UserService;
import com.baomidou.dynamic.datasource.annotation.DSTransactional;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;

@Service
@Slf4j
public class UserServiceImpl implements UserService {
    @Resource
    private UsersPOMapper usersPOMapper;
    @Resource
    private UsersDepartmentPOMapper usersDepartmentPOMapper;
    @Resource
    private DepartmentsPOMapper departmentsPOMapper;
    @Resource
    private RolesPOMapper rolesPOMapper;

    /**
     * 用户登录
     *
     * @param userCode
     * @param password
     * @return
     */
    @Override
    public UsersPO getUserLogin(String userCode, String password) {
        LambdaQueryWrapper<UsersPO> wrapper = new QueryWrapper<UsersPO>().lambda();
        wrapper.eq(UsersPO::getUserCode, userCode)
                .eq(UsersPO::getUserPassword, password)
                .eq(UsersPO::getEnabled, true)
                .last("Limit 1");
        return usersPOMapper.selectOne(wrapper);
    }

    /**
     * 通过userCode获取用户
     *
     * @param userCode
     * @return
     */
    @Override
    public UsersPO get1User_Usable(String userCode) {
        LambdaQueryWrapper<UsersPO> wrapper = new QueryWrapper<UsersPO>().lambda();
        wrapper.eq(UsersPO::getUserCode, userCode)
                .eq(UsersPO::getEnabled, true)
                .last("LIMIT 1");
        return usersPOMapper.selectOne(wrapper);
    }

    /**
     * 获取一个可用的用户及角色
     *
     * @param userCode
     * @return
     */

    @Override
    public UserRoleDTO get1UserRole_Usable(String userCode) {
        UsersPO user = usersPOMapper.selectOne(new LambdaQueryWrapper<UsersPO>()
                .eq(UsersPO::getUserCode, userCode)
                .eq(UsersPO::getEnabled, true)
                .last("LIMIT 1"));
        if (ObjectUtil.isEmpty(user)) return null;

        RolesPO role = rolesPOMapper.selectOne(new LambdaQueryWrapper<RolesPO>()
                .eq(RolesPO::getRoleID, user.getRoleID())
                .last("LIMIT 1"));
        if (ObjectUtil.isEmpty(role)) return null;

        UserRoleDTO userRoleDTO = new UserRoleDTO();
        userRoleDTO.setUsersPO(user);
        userRoleDTO.setRolesPO(role);
        return userRoleDTO;
    }

    /**
     * 获取一个当前的用户角色
     *
     * @return
     */
    @Override
    public UserRoleDTO get1UserRole_Active() {
        // 获取satoken的rolelist
        List<String> roleList = StpUtil.getRoleList(StpUtil.getLoginIdAsString());
        if (roleList.size() != 1) return null;
        UserRoleDTO userRoleDTO = new UserRoleDTO();
        userRoleDTO.setUsersPO(usersPOMapper.selectOne(new LambdaQueryWrapper<UsersPO>()
                .eq(UsersPO::getUserCode, StpUtil.getLoginIdAsString())));
        userRoleDTO.setRolesPO(rolesPOMapper.selectById(Convert.toInt(roleList.get(0))));
        return userRoleDTO;
    }

    /**
     * 获取一个可用的用户,和制造部权限
     *
     * @param userCode
     * @return
     */
    @Override
    public UserDepartmentDTO get1UserDepartment_Usable(String userCode) {
        // 1.获取用户
        UsersPO user = usersPOMapper.selectOne(new LambdaQueryWrapper<UsersPO>()
                .eq(UsersPO::getUserCode, userCode)
                .eq(UsersPO::getEnabled, true)
                .last("LIMIT 1"));
        if (ObjectUtil.isEmpty(user)) return null;
        // 2.获取用户对应的制造部权限ID
        UsersDepartmentPO usersDepartment = usersDepartmentPOMapper.selectOne(new LambdaQueryWrapper<UsersDepartmentPO>()
                .eq(UsersDepartmentPO::getUserID, user.getUserID()));
        if (ObjectUtil.isEmpty(usersDepartment)) return null;
        // 3.获取用户对应的制造部
        DepartmentsPO department = departmentsPOMapper.selectOne(new LambdaQueryWrapper<DepartmentsPO>()
                .eq(DepartmentsPO::getDepartmentID, usersDepartment.getTopDeptID())
                .eq(DepartmentsPO::getEnabled, true)
                .eq(DepartmentsPO::getParentID, 0)
                .last("Limit 1"));
        if (ObjectUtil.isEmpty(department)) return null;
        // 4.组装数据
        UserDepartmentDTO userDepartmentDTO = new UserDepartmentDTO();
        userDepartmentDTO.setUsersPO(user);
        userDepartmentDTO.setDepartmentsPO(department);
        return userDepartmentDTO;
    }

    @Override
    public UserDepartmentDTO get1UserDepartment_Active() {
        // 获取satoken的permissionList
        List<String> topDeptIDList = StpUtil.getPermissionList(StpUtil.getLoginIdAsString());
        if (topDeptIDList.size() != 1) return null;
        UserDepartmentDTO userDepartmentDTO = new UserDepartmentDTO();
        userDepartmentDTO.setUsersPO(usersPOMapper.selectOne(new LambdaQueryWrapper<UsersPO>()
                .eq(UsersPO::getUserCode, StpUtil.getLoginIdAsString())));
        userDepartmentDTO.setDepartmentsPO(departmentsPOMapper.selectById(Convert.toInt(topDeptIDList.get(0))));
        return userDepartmentDTO;
    }

    /**
     * 获取全部用户,角色,和制造部权限
     *
     * @return
     */
    @Override
    public List<UserInfoDTO> getAllUserInfo(String keyword) {
        // 1.获取制造部权限List
        List<String> topDeptPermisList = StpUtil.getPermissionList(StpUtil.getLoginIdAsString());
        if (topDeptPermisList.size() != 1) return null;
        LambdaQueryWrapper<DepartmentsPO> wrapper = new LambdaQueryWrapper<DepartmentsPO>();
        wrapper.eq(DepartmentsPO::getEnabled, true)
                .eq(DepartmentsPO::getParentID, 0)   //父ID=0
                .ge(DepartmentsPO::getDepartmentID, 10)      //自己的ID>10
                // 非超级管理员
                .eq(Convert.toInt(topDeptPermisList.get(0)) >= 10, DepartmentsPO::getDepartmentID, topDeptPermisList.get(0));
        List<DepartmentsPO> topDeptList = departmentsPOMapper.selectList(wrapper);
        if (CollUtil.isEmpty(topDeptList)) return null;
        // 1.1 组装成topDeptID List
        List<Integer> topDeptIDList = CollUtil.list(false);
        CollUtil.forEach(topDeptList, (topDept, index) -> {
            topDeptIDList.add(topDept.getDepartmentID());
        });
        // 2.获取用户与Department的列表
        LambdaQueryWrapper<UsersDepartmentPO> wrapper1 = new LambdaQueryWrapper<>();
        wrapper1.in(UsersDepartmentPO::getTopDeptID, topDeptIDList);
        List<UsersDepartmentPO> usersDepartmentPOList = usersDepartmentPOMapper.selectList(wrapper1);
        if (CollUtil.isEmpty(usersDepartmentPOList)) return null;
        // 2.1 组装成 userIDList
        List<Integer> userIDList = CollUtil.list(false);
        CollUtil.forEach(usersDepartmentPOList.iterator(), (usersDepartment, index) -> {
            userIDList.add(usersDepartment.getUserID());
        });
        // 3.获取权限对应的用户
        LambdaQueryWrapper<UsersPO> wrapper2 = new LambdaQueryWrapper<>();
        wrapper2.in(UsersPO::getUserID, userIDList)
                .gt(UsersPO::getUserID, 1);
        List<UsersPO> usersPOList = usersPOMapper.selectList(wrapper2);
        if (CollUtil.isEmpty(usersPOList)) return null;
        // 3.获取全部角色
        List<RolesPO> rolePOList = rolesPOMapper.selectList(null);

        // 4.组装数据
        List<UserInfoDTO> userInfoDTOList = CollUtil.list(false);
        CollUtil.forEach(usersPOList.iterator(), (user, index) -> {
            UserInfoDTO userInfoDTO = new UserInfoDTO();
            userInfoDTO.setUser(user);
            userInfoDTO.setRole(CollUtil.findOne(rolePOList, rolesPO -> {
                        return rolesPO.getRoleID().equals(user.getRoleID());
                    })
            );
            UsersDepartmentPO uzDepartment = CollUtil.findOne(usersDepartmentPOList, usersDepartmentPO -> {
                return user.getUserID().equals(usersDepartmentPO.getUserID());
            });
            userInfoDTO.setTopDept(CollUtil.findOne(topDeptList, topDept -> {
                        return topDept.getDepartmentID().equals(uzDepartment.getTopDeptID());
                    })
            );
            userInfoDTOList.add(userInfoDTO);
        });

        //5.过滤数据
        CollUtil.removeNull(userInfoDTOList);
        CollUtil.filter(userInfoDTOList,userInfoDTO -> {
            return (ObjectUtil.isNotEmpty(userInfoDTO.getTopDept()));
        });
        //6.关键字搜索
        CollUtil.filter(userInfoDTOList,userInfoDTO->{
           return (userInfoDTO.getUser().getUserCode().contains(keyword)|| userInfoDTO.getUser().getUserFullName().contains(keyword));
        });

        return userInfoDTOList;
    }

    @Override
    public int uptUserEnabled(Integer userID, Boolean enabled) {
        UsersPO usersPO = new UsersPO();
        usersPO.setUserID(userID);
        usersPO.setEnabled(enabled);
        return usersPOMapper.updateById(usersPO);
    }

    @Override
    public int delUser(Integer userID) {
        return usersPOMapper.deleteById(userID);
    }

    @Override
    @DSTransactional
    public int addUser(UserInfoDTO userInfoDTO) {
        UsersPO user = userInfoDTO.getUser();
        user.setUserPassword("8888");
        user.setEnabled(true);
        user.setDeleted(false);
        UsersPO tmpUser = usersPOMapper.get1NoCondition(user);
        UsersDepartmentPO usersDepartmentPO = new UsersDepartmentPO();
        int res1=0;
        int res2=0;
        // 当员工号从未出现过
        if(ObjectUtil.isEmpty(tmpUser)){
            res1 = usersPOMapper.insert(user);
            usersDepartmentPO.setUserID(user.getUserID());
            usersDepartmentPO.setTopDeptID(userInfoDTO.getTopDept().getDepartmentID());
            res2 =usersDepartmentPOMapper.insert(usersDepartmentPO);
        }else {     //员工号是被删除过的
            res1=usersPOMapper.uptUserNoCondition(user);
            usersDepartmentPO.setUserID(tmpUser.getUserID());
            usersDepartmentPO.setTopDeptID(userInfoDTO.getTopDept().getDepartmentID());
            res2=usersDepartmentPOMapper.updateById(usersDepartmentPO);
        }
        if(res1<1 || res2<1) return 0;
        return 1;
    }

    @Override
    @DSTransactional
    public int uptUser(UserInfoDTO userInfoDTO) {
        UsersPO user = userInfoDTO.getUser();
        int res1 = usersPOMapper.updateById(user);
        UsersDepartmentPO usersDepartmentPO = new UsersDepartmentPO();
        usersDepartmentPO.setUserID(user.getUserID());
        usersDepartmentPO.setTopDeptID(userInfoDTO.getTopDept().getDepartmentID());
        int res2= usersDepartmentPOMapper.updateById(usersDepartmentPO);
        if(res1<1 ||res2<1) return 0;
        return 1;
    }

    @Override
    public int uptUserPwd(String userCode, String oldPassword, String newPassword) {
        UsersPO userPO = new UsersPO();
        userPO.setUserPassword(newPassword);
        return usersPOMapper.update(userPO, new LambdaQueryWrapper<UsersPO>().eq(UsersPO::getUserCode, userCode).eq(UsersPO::getUserPassword, oldPassword));
    }

}
